/* 
 * Description: Recognize the 32-bit hexadecimal integer from stdin
 * Pattern: 0[xX]([0-9a-fA-F]{1,8})
 */

%{
#include <stdio.h>
#include <stdlib.h>
#define OPERATOR 1
#define OPERAND 2
int tokens = 0;
int error = 0;

struct is {
  int type;
  union value {
    char operator;
    float operand;
  }val;
};
struct is in[50];
float stack[50];
int stacktop = 0;
void push (float element);
float pop ();

void push (float element) {
  if (stacktop < 50){
    stack[stacktop++] = element;
  }
  else {
    stacktop = 0;
    error = 1;
  }
}

float pop(){
  if (stacktop > 0){
    return (stack[--stacktop]);
  }
  else {
    stacktop = 0;
    error = 1;
  }
}


float prefix_eval(struct is *str){
  int l;
  float t,q;
  l = tokens-1;
  while (l>=0 && !error){
    //printf ("Currently Parsing element at %d ...%f\n",l,str[l]);
    if (str[l].type == OPERATOR) {
      t=pop();
      q=pop();
      if (str[l].val.operator == '+') {
          push(t+q);
      }
      else if (str[l].val.operator == '-') {
          push(t-q);
      }
      else if (str[l].val.operator == '*') {
          push(t*q);
      }
      else {
          push(t/q);
      }
    }
    else {
        push(str[l].val.operand);
    }
    l--;
  }
  return (pop());
}

%}

digit        [0-9]
operator     [+-/*]

%%
{digit}+"."{digit}*|{digit}+ {
 in[tokens].type=OPERAND;
 in[tokens].val.operand = atof(yytext);
 tokens++;

}
{operator}            {
  in[tokens].type = OPERATOR;
  in[tokens].val.operator = yytext[0];
  tokens++;
}

"\n"            {
    float evaluated_expression = prefix_eval (in);
  if (!error) printf ("%.2f\n", evaluated_expression);
  else printf ("InvalidExpressionError\n");
  tokens = 0;
  stacktop = 0;
  error = 0;
}

.        printf("");
%%

main()
{
     int i;
     // printf("Give me your input:\n");
     yylex();
}
